//
// Created by hsj on 2022/2/23.
//
#include <iostream>
#include <string>
#include <valarray>
#ifndef CLION_CPP_STUDENT_H
#define CLION_CPP_STUDENT_H
namespace t_student_with_has_a{
    using std::valarray;
    using std::string;
    using std::istream;
    using std::ostream;
    using std::endl;
    using std::cout;
    using std::cin;

    //一些常量
    const int pupils = 3;
    const int quizzes = 5;

    //使用包含
    class Student{
        private:
            //valarray是一个模板类（java的泛型类）
            //只可以在类内部使用，在外部不可以使用
            typedef valarray<double> ArrayDb;
            //姓名
            string name;
            //成绩
            ArrayDb scores;
            //输出成绩
            ostream & scoresOut(ostream &os)const{
                int i = 0;
                int lim = scores.size();
                if (lim > 0){
                    for (int j = 0; j < lim; ++j) {
                        os<<scores[j]<<"  ";
                        if (j % 5 == 4){
                            os<<endl;
                        }
                    }
                    if (i % 5 != 0){
                        os<<endl;
                    }
                }
                else{
                    os<<"empty array."<<endl;
                }
                return os;
            }
        public:
            Student():name("Null Name"),scores(){}
            //单个时候禁止隐式的初始化
            explicit Student(const string &s):name(s),scores(){}
            //单个时候禁止隐式的初始化[长度初始化n]
            explicit Student(int n):name("Null Name"),scores(n){}
            Student (const string &s,int n):name(s),scores(n){}
            Student(const string &s,const ArrayDb &adb):name(s),scores(adb){}
            Student(const char *str,const double * const pd,int n):name(str),scores(pd,n){}

            //析构函数
            ~Student(){}

            //普通函数
            double Average()const;
            const string &Name()const{
                return name;
            };
            double & operator[](int i){
                return scores[i];
            };
            double operator[](int i)const{
                return scores[i];
            };

            //友元函数解决操作符重载时候的左值[不属于类对象，但是可以使用类对象的成员函数等]
            friend istream& operator>>(istream &is,Student &stu){
                is>>stu.name;
                return is;
            };
            //非操作符号
            friend istream & getline(istream &is,Student &stu){
                getline(is,stu.name);
                return is;
            };

            //打印学生信息
            friend ostream& operator<<(ostream &os,Student &stu){
                os<<"Scores for:"<<stu.name<<endl;
                stu.scoresOut(os);
                return os;
            };

    };

    //使用
    void test();
    void set(Student &stu,int n);
}
#endif //CLION_CPP_STUDENT_H
